// 引入语音命令识别模型库 - 这里使用的是 TensorFlow.js 的语音识别模型
import * as speechCommands from '@tensorflow-models/speech-commands';

// 模型路径配置 - 这里指向本地服务器的8080端口，需要先启动静态服务器
// 注意：如果你没启动服务器，这个代码会报错找不到模型文件
const MODEL_PATH = 'http://127.0.0.1:8080/speech';

// 页面加载完成后执行的主函数
window.onload = async () => {
    // 创建语音识别器实例
    // 参数1: BROWSER_FFT - 使用浏览器的FFT实现音频分析
    // 参数2: null - 不指定特定的词汇表，使用默认词汇
    // 参数3-4: 模型文件和元数据文件的路径
    const recognizer = speechCommands.create(
        'BROWSER_FFT',
        null,
        MODEL_PATH + '/model.json',      // 模型文件路径
        MODEL_PATH + '/metadata.json'    // 元数据文件路径
    );

    // 确保模型加载完成 - 这是一个异步操作，会等待模型下载并加载到内存
    await recognizer.ensureModelLoaded();
    console.log('模型加载成功，可以开始语音识别了');

    // 获取可用的命令标签，去掉前两个（通常是 '_background_noise_' 和 'unknown'）
    const labels = recognizer.wordLabels().slice(2);
    console.log('可用的语音命令:', labels);

    // 获取结果显示区域的DOM元素
    const resultEl = document.querySelector('#result');

    // 初始渲染命令标签 - 将每个命令显示为一个div元素
    resultEl.innerHTML = labels.map(l => `
        <div>${l}</div>
    `).join('');

    // 开始监听语音 - 这会启动麦克风并持续进行语音识别
    recognizer.listen(
        // 回调函数：当识别到语音时触发
        result => {
            // 从结果中提取置信度分数数组
            const { scores } = result;
            
            // 找到最高置信度的分数和对应的索引
            console.log('scores:', scores);
            const maxValue = Math.max(...scores);
            // 减去2是因为我们之前去掉了前两个标签
            const index = scores.indexOf(maxValue) - 2;
            
            console.log(`识别到: ${labels[index] || '未知'}，置信度: ${(maxValue * 100).toFixed(2)}%`);
            
            // 更新界面，将识别到的命令标签高亮显示为绿色
            resultEl.innerHTML = labels.map((l, i) => `
            <div style="background: ${i === index ? 'green' : '#f0f0f0'}">${l}</div>
            `).join('');
        },
        // 配置选项
        {
            overlapFactor: 0.2,        // 重叠因子 - 控制连续音频片段的重叠程度，值越大响应越灵敏
            probabilityThreshold: 0.9  // 概率阈值 - 只有当置信度超过90%时才会触发识别结果
        }
    );

    // 注意事项：
    // 1. 首次访问页面时会请求麦克风权限，需要用户授权
    // 2. 如果模型加载失败，需要检查服务器是否正确运行
    // 3. 安静环境下识别效果更好，噪音大的地方可能会有误识别
};

/*
使用说明：
1. 确保本地启动了静态服务器，端口为8080
2. 将模型文件放在服务器的speech目录下
3. 打开页面后，等待模型加载完成
4. 对着麦克风说出训练好的命令词（如：up, down, left, right等）
5. 被识别到的命令会显示为绿色背景

常见问题：
- 模型加载失败：检查服务器是否启动，端口是否正确
- 没有识别结果：确保麦克风已授权，说话声音清晰且在安静环境下
- 误识别率高：可以尝试调整probabilityThreshold值
*/